package org.wlldTest.lesson13;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.dromara.easyai.config.RZ;
import org.dromara.easyai.entity.Box;
import org.dromara.easyai.entity.ThreeChannelMatrix;
import org.dromara.easyai.tools.ImageTools;
import org.dromara.easyai.tools.NMS;
import org.dromara.easyai.tools.Picture;
import org.dromara.easyai.yolo.*;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Data {
    public static void main(String[] args) throws Exception {
        //testData();
        testMyData();
        //dataA();
    }

    public static void dataA() throws Exception {
        ImageTools imageTools = new ImageTools();
        YoloConfig yoloConfig = new YoloConfig();
        yoloConfig.setWindowWidth(90);
        yoloConfig.setWindowHeight(120);
        yoloConfig.setTypeNub(2);
        yoloConfig.setEnhance(20);
        yoloConfig.setPth(0.9);
        FastYolo fastYolo = new FastYolo(yoloConfig);
        fastYolo.insertModel(readCreatorModel(1));

        String url = "D:\\testPic/tmd.png";
        ThreeChannelMatrix threeChannelMatrix = Picture.getThreeMatrix(url,false);
        List<OutBox> outBoxes = fastYolo.look(threeChannelMatrix, 1);
        if (outBoxes != null) {
            imageTools.drawBox(url, outBoxes, "D:\\testPic/tmdTest.png", 22);
        }

    }

    public static void testMyData() throws Exception {
        List<MyImage> myImages = new ArrayList<>();
        MyImage a = new MyImage();
        ImageTools imageTools = new ImageTools();
        a.setUrl("/Users/lidapeng/job/testPic/a1.jpg");
        a.setX(80);
        a.setY(69);
        a.setSize(136);
        a.setTypeID(1);
        MyImage b = new MyImage();
        b.setUrl("/Users/lidapeng/job/testPic/b1.jpg");
        b.setX(78);
        b.setY(70);
        b.setSize(127);
        b.setTypeID(2);
        for (int i = 0; i < 10; i++) {
            if (i % 2 == 0) {
                myImages.add(a);
            } else {
                myImages.add(b);
            }
        }
        ThreeChannelMatrix back = creatImg2(myImages);
        String url = "/Users/lidapeng/job/testPic/tmd.png";
        imageTools.writeImage(back, url);
        YoloConfig yoloConfig = new YoloConfig();
        yoloConfig.setWindowWidth(90);
        yoloConfig.setWindowHeight(120);
        yoloConfig.setTypeNub(2);
        yoloConfig.setCheckStepReduce(1);
        yoloConfig.setRegularModel(RZ.L2);
        yoloConfig.setCheckStepReduce(0.5);
        yoloConfig.setRegular(0.01);
        yoloConfig.setPth(0.7);
       // yoloConfig.setCoreNumber(20);
        FastYolo fastYolo = new FastYolo(yoloConfig);
        fastYolo.insertModel(readCreatorModel(1));
        ///// 实际检测部分
        ThreeChannelMatrix threeChannelMatrix = Picture.getThreeMatrix(url,false);
        long t1 = System.currentTimeMillis();
        List<OutBox> outBoxes = fastYolo.look(threeChannelMatrix, 2);
        long t2 = System.currentTimeMillis() - t1;//5386
        System.out.println(t2);
        if (outBoxes != null) {
            for (OutBox outBox : outBoxes) {
                if (outBox.getTypeID().equals("1")) {
                    outBox.setTypeID("汽水");
                } else {
                    outBox.setTypeID("钙奶");
                }
            }
            imageTools.drawBox(url, outBoxes, "/Users/lidapeng/job/testPic/test.png", 30);
        } else {
            System.out.println("无检出物");
        }

    }

    private static YoloModel readCreatorModel(int i) {
        File file = new File("/Users/lidapeng/job/testPic/model" + i + ".json");
        String a = readPaper(file);
        return JSONObject.parseObject(a, YoloModel.class);
    }

    private static String readPaper(File file) {
        InputStream read = null;
        String context = null;
        try {
            read = Files.newInputStream(file.toPath());
            byte[] bt = new byte[read.available()];
            read.read(bt);
            context = new String(bt, StandardCharsets.UTF_8);
            read.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (read != null) {
                try {
                    read.close(); //确保关闭
                } catch (IOException el) {
                }
            }
        }
        return context;
    }

    public static void testData() throws Exception {
        List<MyImage> myImages = new ArrayList<>();//产品位置信息
        YoloConfig yoloConfig = new YoloConfig();//目标检测配置类
        yoloConfig.setWindowWidth(90);//检测窗口宽度
        yoloConfig.setWindowHeight(120);//检测窗口高度
        yoloConfig.setTypeNub(2);
        yoloConfig.setEnhance(1);//循环训练 enhance * 训练样本数据量=[1000,2000] 不是
        yoloConfig.setContainIouTh(0.25);//检测框是否包含内容物交并比阈值判定
        yoloConfig.setStepReduce(0.5);
        yoloConfig.setPth(0.4);
        FastYolo fastYolo = new FastYolo(yoloConfig);
        MyImage a = new MyImage();
        a.setUrl("/Users/lidapeng/job/testPic/a1.jpg");//气泡水
        a.setX(80);
        a.setY(69);
        a.setSize(136);
        a.setTypeID(1);
        MyImage b = new MyImage();
        b.setUrl("/Users/lidapeng/job/testPic/b1.jpg");
        b.setX(78);
        b.setY(70);
        b.setSize(127);
        b.setTypeID(2);
        List<YoloSample> yoloSamples = new ArrayList<>();
        for (int k = 1; k < 401; k++) {
            myImages.clear();
            String url = "/Users/lidapeng/job/testPic/temple/test" + k + ".png";
            for (int i = 0; i < 10; i++) {
                if (i % 2 == 0) {
                    myImages.add(a);
                } else {
                    myImages.add(b);
                }
            }
            creatImg(myImages, yoloSamples, url);
        }
        fastYolo.toStudy(yoloSamples);//耗时行为
        YoloModel yoloModel = fastYolo.getModel();
        writeModel(JSON.toJSONString(yoloModel), "/Users/lidapeng/job/testPic/model3.json");
    }

    private static void writeModel(String model, String url) throws IOException {//写出模型与 激活参数
        OutputStreamWriter out = new OutputStreamWriter(Files.newOutputStream(Paths.get(url)), StandardCharsets.UTF_8);
        out.write(model);
        out.close();
    }

    public static ThreeChannelMatrix creatImg2(List<MyImage> myImages) throws Exception {
        ThreeChannelMatrix back = Picture.getThreeMatrix("/Users/lidapeng/job/testPic/c1.jpg",false);//背景
        int x = back.getX();
        int y = back.getY();
        Random random = new Random();
        List<Box> boxes = new ArrayList<>();
        for (MyImage image : myImages) {
            int size = image.getSize();
            ThreeChannelMatrix b = Picture.getThreeMatrix(image.getUrl(),false);//物品
            ThreeChannelMatrix rb = b.cutChannel(image.getY(), image.getX(), size, size);
            Box box = new Box();
            box.setTypeID(image.getTypeID());
            int rx;
            int ry;
            do {
                rx = random.nextInt(x - size);
                ry = random.nextInt(y - size);
                box.setX(rx);
                box.setY(ry);
                box.setxSize(size);
                box.setySize(size);
            } while (!ok(boxes, box));
            back.fill(rx, ry, rb);
        }
        return back;
    }

    public static void creatImg(List<MyImage> myImages, List<YoloSample> yoloSamples, String url) throws Exception {
        ImageTools imageTools = new ImageTools();//图像输出验证工具
        YoloSample yoloSample = new YoloSample();
        yoloSamples.add(yoloSample);
        yoloSample.setLocationURL(url);
        List<YoloBody> yoloBodies = new ArrayList<>();
        yoloSample.setYoloBodies(yoloBodies);
        ThreeChannelMatrix back = Picture.getThreeMatrix("/Users/lidapeng/job/testPic/c1.jpg",false);//背景
        int x = back.getX();//行数
        int y = back.getY();//列数
        Random random = new Random();
        List<Box> boxes = new ArrayList<>();// 交并比=0
        for (MyImage image : myImages) {
            int size = image.getSize();//宽高
            ThreeChannelMatrix b = Picture.getThreeMatrix(image.getUrl(),false);//将饮料图片转化为像素矩阵
            //将饮料从原图像中切割出来
            ThreeChannelMatrix rb = b.cutChannel(image.getY(), image.getX(), size, size);
            Box box = new Box();
            box.setTypeID(image.getTypeID());
            int rx;
            int ry;
            do {
                rx = random.nextInt(x - size);
                ry = random.nextInt(y - size);
                box.setX(rx);
                box.setY(ry);
                box.setxSize(size);
                box.setySize(size);
            } while (!ok(boxes, box));
            YoloBody yoloBody = new YoloBody();
            yoloBody.setX(ry);
            yoloBody.setY(rx);
            yoloBody.setWidth(size);
            yoloBody.setHeight(size);
            yoloBody.setTypeID(image.getTypeID());
            yoloBodies.add(yoloBody);
            back.fill(rx, ry, rb);
        }
        imageTools.writeImage(back, url);
    }

    private static boolean ok(List<Box> boxes, Box box) {
        boolean ok = true;
        NMS nms = new NMS(0.1);
        for (Box myBox : boxes) {
            if (nms.getSRatio(myBox, box, true) > 0) {
                ok = false;
                break;
            }
        }
        if (ok) {
            boxes.add(box);
        }
        return ok;
    }
}
